package com.sinosoft.hydra.um.domain.permission;

import cn.com.sinux.spring.commons.TreeNode;
import com.sinosoft.hydra.um.constant.BaseConstant;
import cn.com.sinux.spring.utils.ValidatorUtils;;
import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "T_P_BOM")
public class TPBom implements Serializable, TreeNode<TPBom> {
    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_p_bom.id
     *
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    @Size(max = 50, message = "tpbom.id.max.overflow")
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(name = "ID")
    private String id;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_p_bom.code
     *
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    @NotNull(message = "tpbom.code.not.null")
    @Size(max = 50, message = "tpbom.code.max.overflow")
    @Column(name = "CODE")
    private String code;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_p_bom.p_name
     *
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    @NotNull(message = "tpbom.pname.not.null")
    @Size(max = 50, message = "tpbom.pname.max.overflow")
    @Column(name = "P_NAME")
    private String pName;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_p_bom.number
     *
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    @Transient
    private Integer number;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_p_bom.status
     *
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    @NotNull(message = "tpbom.status.not.null")
    @Size(max = 50, message = "tpbom.status.max.overflow")
    @Column(name = "STATUS")
    private String status;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_p_bom.node_type
     *
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    @Size(max = 50, message = "tpbom.nodetype.max.overflow")
    @Column(name = "NODE_TYPE")
    private String bomType;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_p_bom.remark
     *
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    @Size(max = 400, message = "tpbom.remark.max.overflow")
    @Column(name = "REMARK")
    private String remark;

    @OneToMany(mappedBy = "tPBom", cascade = CascadeType.DETACH)
    private List<TEBom> teBoms;

    public List<TEBom> getTeBoms() {
        return teBoms;
    }

    public void setTeBoms(List<TEBom> teBoms) {
        this.teBoms = teBoms;
    }

    @Transient
    private Integer nodeLevel;

    public Integer getNodeLevel() {
        return nodeLevel;
    }

    public void setNodeLevel(Integer nodeLevel) {
        this.nodeLevel = nodeLevel;
    }

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database table t_p_bom
     *
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    private static final long serialVersionUID = 1L;
    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_p_bom_relation.children_id
     *
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    /**
     * 父级集合
     *
     * @return List<tPBoms>
     */
    @OneToMany(mappedBy = "ref", fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    private List<TPBomRelation> tpBomRelations;

    public List<TPBomRelation> getTpBomRelations() {
        return tpBomRelations;
    }

    public void setTpBomRelations(List<TPBomRelation> tpBomRelations) {
        this.tpBomRelations = tpBomRelations;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_p_bom.id
     *
     * @return the value of t_p_bom.id
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public String getId() {
        return id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_p_bom.id
     *
     * @param id the value for t_p_bom.id
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_p_bom.code
     *
     * @return the value of t_p_bom.code
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public String getCode() {
        return code;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_p_bom.code
     *
     * @param code the value for t_p_bom.code
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public void setCode(String code) {
        this.code = code;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_p_bom.p_name
     *
     * @return the value of t_p_bom.p_name
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public String getpName() {
        return pName;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_p_bom.p_name
     *
     * @param pName the value for t_p_bom.p_name
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public void setpName(String pName) {
        this.pName = pName;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_p_bom.number
     *
     * @return the value of t_p_bom.number
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public Integer getNumber() {
        return number;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_p_bom.number
     *
     * @param number the value for t_p_bom.number
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public void setNumber(Integer number) {
        this.number = number;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_p_bom.status
     *
     * @return the value of t_p_bom.status
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public String getStatus() {
        return status;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_p_bom.status
     *
     * @param status the value for t_p_bom.status
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public void setStatus(String status) {
        this.status = status;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_p_bom.node_type
     *
     * @return the value of t_p_bom.node_type
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public String getBomType() {
        return bomType;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_p_bom.node_type
     *
     * @param bomType the value for t_p_bom.node_type
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */
    public void setBomType(String bomType) {
        this.bomType = bomType;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_p_bom
     *
     * @mbggenerated Tue Jun 28 12:59:59 CST 2016
     */

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", code=").append(code);
        sb.append(", pName=").append(pName);
        sb.append(", number=").append(number);
        sb.append(", status=").append(status);
        sb.append(", bomType=").append(bomType);
        sb.append("]");
        return sb.toString();
    }

    @Transient
    private String refId;

    public String getRefId() {
        return refId;
    }

    public void setRefId(String refId) {
        this.refId = refId;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public String getState(){
        return ValidatorUtils.isArrayNotEmpty(getTpBomRelations()) ? "closed" : "";
    }

    public boolean isCanBuild(){
        if(!BaseConstant.BomStatus.PUBLISH.name().equals(this.status)){
            return false;
        }
        List<TPBom> children = getChildren();
        if (ValidatorUtils.isArrayNotEmpty(children)) {
            for (TPBom child : children) {
                if (child.getNonBuild() < child.getNumber()) {
                    return false;
                }
            }
        }
        return true;
    }
    public int getNonBuild() {
        if (getSuitAll() > 0) {
            int i = 0;
            for (TEBom teBom : getTeBoms()) {
                if (BaseConstant.EBomType.E_BOM_TYPE_UN_BUILD.name().equals(teBom.getBomType())) {
                    i++;
                }
            }
            return i;
        }
        return 0;
    }


    public int getSuitAll() {
        return ValidatorUtils.isArrayEmpty(this.getTeBoms()) ? 0 : this.getTeBoms().size();
    }

    public void setChildren(List<TPBom> tpBoms) {
        this.tpBomRelations = new ArrayList<TPBomRelation>(tpBoms.size());
        for (TPBom tpBom : tpBoms) {
            TPBomRelation tpBomRelation = new TPBomRelation();
            tpBomRelation.setChild(tpBom);
            tpBomRelation.setNumber(tpBom.getNumber());
            tpBomRelation.setRef(this);
            tpBomRelations.add(tpBomRelation);
        }
    }

    public TPBom addChild(TPBom tpBom) {
        if (this.tpBomRelations == null) {
            this.tpBomRelations = new ArrayList<TPBomRelation>();
        }
        boolean find = false;
        if (StringUtils.isNotBlank(tpBom.getCode())) {
            for (TPBomRelation tpBomRelation : this.tpBomRelations) {
                if (tpBom.getCode().equals(tpBomRelation.getChild().getCode())) {
                    tpBomRelation.setNumber(tpBomRelation.getNumber() + 1);
                    find = true;
                    break;
                }
            }
            if (!find) {
                TPBomRelation tpBomRelation = new TPBomRelation();
                tpBomRelation.setNumber(tpBom.getNumber());
                tpBomRelation.setChild(tpBom);
                tpBomRelation.setRef(this);
                this.tpBomRelations.add(tpBomRelation);
            }
        }
        return this;
    }

    public List<TPBom> getChildren() {
        List<TPBom> tpBoms = new ArrayList<TPBom>();
        if (ValidatorUtils.isArrayNotEmpty(tpBomRelations)) {
            for (TPBomRelation tpBomRelation : tpBomRelations) {
                TPBom tpBom = tpBomRelation.getChild();
                tpBom.setNumber(tpBomRelation.getNumber());
                tpBomRelation.setRef(this);
                tpBoms.add(tpBom);
            }
        }
        return tpBoms;
    }
}